home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 301-325 / disk_319 / cnewssrc / cnews.orig.lzh / contrib / dirfns < prev    next >
Text File  |  1989-06-27  |  11KB  |  483 lines

  1. echo 'directory.3':
  2. sed 's/^X//' >'directory.3' <<'!'
  3. X.TH DIRECTORY 3 imported
  4. X.DA 9 Oct 1985
  5. X.SH NAME
  6. Xopendir, readdir, telldir, seekdir, rewinddir, closedir \- high-level director
  7.  operations
  8. X.SH SYNOPSIS
  9. X.B #include <sys/types.h>
  10. X.br
  11. X.B #include <ndir.h>
  12. X.PP
  13. X.SM
  14. X.B DIR
  15. X.B *opendir(filename)
  16. X.br
  17. X.B char *filename;
  18. X.PP
  19. X.SM
  20. X.B struct direct
  21. X.B *readdir(dirp)
  22. X.br
  23. X.B DIR *dirp;
  24. X.PP
  25. X.SM
  26. X.B long
  27. X.B telldir(dirp)
  28. X.br
  29. X.B DIR *dirp;
  30. X.PP
  31. X.SM
  32. X.B seekdir(dirp, loc)
  33. X.br
  34. X.B DIR *dirp;
  35. X.br
  36. X.B long loc;
  37. X.PP
  38. X.SM
  39. X.B rewinddir(dirp)
  40. X.br
  41. X.B DIR *dirp;
  42. X.PP
  43. X.SM
  44. X.B closedir(dirp)
  45. X.br
  46. X.B DIR *dirp;
  47. X.SH DESCRIPTION
  48. XThis library provides high-level primitives for directory scanning,
  49. Xsimilar to those available for 4.2BSD's (very different) directory system.
  50. X.\"The purpose of this library is to simulate
  51. X.\"the new flexible length directory names of 4.2bsd UNIX
  52. X.\"on top of the old directory structure of v7.
  53. XIt incidentally provides easy portability to and from 4.2BSD (insofar
  54. Xas such portability is not compromised by other 4.2/VAX dependencies).
  55. X.\"It allows programs to be converted immediately
  56. X.\"to the new directory access interface,
  57. X.\"so that they need only be relinked
  58. X.\"when moved to 4.2bsd.
  59. X.\"It is obtained with the loader option
  60. X.\".BR \-lndir .
  61. X.PP
  62. X.I Opendir
  63. Xopens the directory named by
  64. X.I filename
  65. Xand associates a
  66. X.I directory stream
  67. Xwith it.
  68. X.I Opendir
  69. Xreturns a pointer to be used to identify the
  70. X.I directory stream
  71. Xin subsequent operations.
  72. XThe pointer
  73. X.SM
  74. X.B NULL
  75. Xis returned if
  76. X.I filename
  77. Xcannot be accessed or is not a directory.
  78. X.PP
  79. X.I Readdir
  80. Xreturns a pointer to the next directory entry.
  81. XIt returns
  82. X.B NULL
  83. Xupon reaching the end of the directory or detecting
  84. Xan invalid
  85. X.I seekdir
  86. Xoperation.
  87. X.PP
  88. X.I Telldir
  89. Xreturns the current location associated with the named
  90. X.I directory stream.
  91. X.PP
  92. X.I Seekdir
  93. Xsets the position of the next
  94. X.I readdir
  95. Xoperation on the
  96. X.I directory stream.
  97. XThe new position reverts to the one associated with the
  98. X.I directory stream
  99. Xwhen the
  100. X.I telldir
  101. Xoperation was performed.
  102. XValues returned by
  103. X.I telldir
  104. Xare good only for the lifetime of the DIR pointer from 
  105. Xwhich they are derived.
  106. XIf the directory is closed and then reopened, 
  107. Xthe 
  108. X.I telldir
  109. Xvalue may be invalidated
  110. Xdue to undetected directory compaction in 4.2BSD.
  111. XIt is safe to use a previous
  112. X.I telldir
  113. Xvalue immediately after a call to
  114. X.I opendir
  115. Xand before any calls to
  116. X.I readdir.
  117. X.PP
  118. X.I Rewinddir
  119. Xresets the position of the named
  120. X.I directory stream
  121. Xto the beginning of the directory.
  122. X.PP
  123. X.I Closedir
  124. Xcauses the named
  125. X.I directory stream
  126. Xto be closed,
  127. Xand the structure associated with the DIR pointer to be freed.
  128. X.PP
  129. XA
  130. X.I direct
  131. Xstructure is as follows:
  132. X.PP
  133. X.RS
  134. X.nf
  135. Xstruct    direct {
  136. X    /* unsigned */ long    d_ino;    /* inode number of entry */
  137. X    unsigned short    d_reclen;    /* length of this record */
  138. X    unsigned short    d_namlen;    /* length of string in d_name */
  139. X    char    d_name[MAXNAMLEN + 1];    /* name must be no longer than this */
  140. X};
  141. X.fi
  142. X.RE
  143. X.PP
  144. XThe
  145. X.I d_reclen
  146. Xfield is meaningless in non-4.2BSD systems and should be ignored.
  147. XThe use of a
  148. X.I long
  149. Xfor
  150. X.I d_ino
  151. Xis also a 4.2BSDism;
  152. X.I ino_t
  153. X(see
  154. X.IR types (5))
  155. Xshould be used elsewhere.
  156. XThe macro
  157. X.I DIRSIZ(dp)
  158. Xgives the minimum memory size needed to hold the
  159. X.I direct
  160. Xvalue pointed to by
  161. X.IR dp ,
  162. Xwith the minimum necessary allocation for
  163. X.IR d_name .
  164. X.PP
  165. XThe preferred way to search the current directory for entry ``name'' is:
  166. X.PP
  167. X.RS
  168. X.nf
  169. X    len = strlen(name);
  170. X    dirp = opendir(".");
  171. X    if (dirp == NULL) {
  172. X        fprintf(stderr, "%s: can't read directory .\\n", argv[0]);
  173. X        return NOT_FOUND;
  174. X    }
  175. X    while ((dp = readdir(dirp)) != NULL)
  176. X        if (dp->d_namlen == len && strcmp(dp->d_name, name) == 0) {
  177. X            closedir(dirp);
  178. X            return FOUND;
  179. X        }
  180. X    closedir(dirp);
  181. X    return NOT_FOUND;
  182. X.RE
  183. X.\".SH LINKING
  184. X.\"This library is accessed by specifying ``-lndir'' as the
  185. X.\"last argument to the compile line, e.g.:
  186. X.\".PP
  187. X.\"    cc -I/usr/include/ndir -o prog prog.c -lndir
  188. X.SH "SEE ALSO"
  189. Xopen(2),
  190. Xclose(2),
  191. Xread(2),
  192. Xlseek(2)
  193. X.SH HISTORY
  194. XWritten by
  195. XKirk McKusick at Berkeley (ucbvax!mckusick).
  196. XMiscellaneous bug fixes from elsewhere.
  197. XThe size of the data structure has been decreased to avoid excessive
  198. Xspace waste under V7 (where filenames are 14 characters at most).
  199. XFor obscure historical reasons, the include file is also available
  200. Xas
  201. X.IR <ndir/sys/dir.h> .
  202. XThe Berkeley version lived in a separate library (\fI\-lndir\fR),
  203. Xwhereas ours is
  204. Xpart of the C library, although the separate library is retained to
  205. Xmaximize compatibility.
  206. X.PP
  207. XThis manual page has been substantially rewritten to be informative in
  208. Xthe absence of a 4.2BSD manual.
  209. X.SH BUGS
  210. XThe
  211. X.I DIRSIZ
  212. Xmacro actually wastes a bit of space due to some padding requirements
  213. Xthat are an artifact of 4.2BSD.
  214. X.PP
  215. XThe returned value of
  216. X.I readdir
  217. Xpoints to a static area that will be overwritten by subsequent calls.
  218. X.PP
  219. XThere are some unfortunate name conflicts with the \fIreal\fR V7
  220. Xdirectory structure definitions.
  221. !
  222. echo 'dir.h':
  223. sed 's/^X//' >'dir.h' <<'!'
  224. X/*    dir.h    4.4    82/07/25    */
  225. X
  226. X/*
  227. X * A directory consists of some number of blocks of DIRBLKSIZ
  228. X * bytes, where DIRBLKSIZ is chosen such that it can be transferred
  229. X * to disk in a single atomic operation (e.g. 512 bytes on most machines).
  230. X *
  231. X * Each DIRBLKSIZ byte block contains some number of directory entry
  232. X * structures, which are of variable length.  Each directory entry has
  233. X * a struct direct at the front of it, containing its inode number,
  234. X * the length of the entry, and the length of the name contained in
  235. X * the entry.  These are followed by the name padded to a 4 byte boundary
  236. X * with null bytes.  All names are guaranteed null terminated.
  237. X * The maximum length of a name in a directory is MAXNAMLEN.
  238. X *
  239. X * The macro DIRSIZ(dp) gives the amount of space required to represent
  240. X * a directory entry.  Free space in a directory is represented by
  241. X * entries which have dp->d_reclen >= DIRSIZ(dp).  All DIRBLKSIZ bytes
  242. X * in a directory block are claimed by the directory entries.  This
  243. X * usually results in the last entry in a directory having a large
  244. X * dp->d_reclen.  When entries are deleted from a directory, the
  245. X * space is returned to the previous entry in the same directory
  246. X * block by increasing its dp->d_reclen.  If the first entry of
  247. X * a directory block is free, then its dp->d_ino is set to 0.
  248. X * Entries other than the first in a directory do not normally have
  249. X * dp->d_ino set to 0.
  250. X */
  251. X#define DIRBLKSIZ    512
  252. X#ifdef VMUNIX
  253. X#define    MAXNAMLEN    255
  254. X#else
  255. X#define    MAXNAMLEN    14
  256. X#endif
  257. X
  258. Xstruct    direct {
  259. X    /* unsigned */ long    d_ino;    /* inode number of entry */
  260. X    unsigned short    d_reclen;    /* length of this record */
  261. X    unsigned short    d_namlen;    /* length of string in d_name */
  262. X    char    d_name[MAXNAMLEN + 1];    /* name must be no longer than this */
  263. X};
  264. X
  265. X/*
  266. X * The DIRSIZ macro gives the minimum record length which will hold
  267. X * the directory entry.  This requires the amount of space in struct direct
  268. X * without the d_name field, plus enough space for the name with a terminating
  269. X * null byte (dp->d_namlen+1), rounded up to a 4 byte boundary.
  270. X */
  271. X#undef DIRSIZ
  272. X#define DIRSIZ(dp) \
  273. X    ((sizeof (struct direct) - (MAXNAMLEN+1)) + (((dp)->d_namlen+1 + 3) &~ 3))
  274. X
  275. X#ifndef KERNEL
  276. X/*
  277. X * Definitions for library routines operating on directories.
  278. X */
  279. Xtypedef struct _dirdesc {
  280. X    int    dd_fd;
  281. X    long    dd_loc;
  282. X    long    dd_size;
  283. X    char    dd_buf[DIRBLKSIZ];
  284. X} DIR;
  285. X#ifndef NULL
  286. X#define NULL 0
  287. X#endif
  288. Xextern    DIR *opendir();
  289. Xextern    struct direct *readdir();
  290. Xextern    long telldir();
  291. X#ifdef void
  292. Xextern    void seekdir();
  293. Xextern    void closedir();
  294. X#endif
  295. X#define rewinddir(dirp)    seekdir((dirp), (long)0)
  296. X#endif KERNEL
  297. !
  298. echo 'makefile':
  299. sed 's/^X//' >'makefile' <<'!'
  300. XDIR = closedir.o opendir.o readdir.o seekdir.o telldir.o
  301. XCFLAGS=-O -I. -Dvoid=int
  302. XDEST=..
  303. X
  304. Xall:    $(DIR)
  305. X
  306. Xmv:    $(DIR)
  307. X    mv $(DIR) $(DEST)
  308. X
  309. Xcpif:    dir.h
  310. X    cp dir.h /usr/include/ndir.h
  311. X
  312. Xclean:
  313. X    rm -f *.o
  314. !
  315. echo 'closedir.c':
  316. sed 's/^X//' >'closedir.c' <<'!'
  317. Xstatic char sccsid[] = "@(#)closedir.c 4.2 3/10/82";
  318. X
  319. X#include <sys/types.h>
  320. X#include <dir.h>
  321. X
  322. X/*
  323. X * close a directory.
  324. X */
  325. Xvoid
  326. Xclosedir(dirp)
  327. X    register DIR *dirp;
  328. X{
  329. X    close(dirp->dd_fd);
  330. X    dirp->dd_fd = -1;
  331. X    dirp->dd_loc = 0;
  332. X    free((char *)dirp);
  333. X}
  334. !
  335. echo 'opendir.c':
  336. sed 's/^X//' >'opendir.c' <<'!'
  337. X/* Copyright (c) 1982 Regents of the University of California */
  338. X
  339. Xstatic char sccsid[] = "@(#)opendir.c 4.4 11/12/82";
  340. X
  341. X#include <sys/types.h>
  342. X#include <sys/stat.h>
  343. X#include <dir.h>
  344. X
  345. X/*
  346. X * open a directory.
  347. X */
  348. XDIR *
  349. Xopendir(name)
  350. X    char *name;
  351. X{
  352. X    register DIR *dirp;
  353. X    register int fd;
  354. X    struct stat statbuf;
  355. X    char *malloc();
  356. X
  357. X    if ((fd = open(name, 0)) == -1)
  358. X        return NULL;
  359. X    if (fstat(fd, &statbuf) == -1 || !(statbuf.st_mode & S_IFDIR)) {
  360. X        close(fd);
  361. X        return NULL;
  362. X    }
  363. X    if ((dirp = (DIR *)malloc(sizeof(DIR))) == NULL) {
  364. X        close (fd);
  365. X        return NULL;
  366. X    }
  367. X    dirp->dd_fd = fd;
  368. X    dirp->dd_loc = 0;
  369. X    dirp->dd_size = 0;    /* so that telldir will work before readdir */
  370. X    return dirp;
  371. X}
  372. !
  373. echo 'readdir.c':
  374. sed 's/^X//' >'readdir.c' <<'!'
  375. X/* Copyright (c) 1982 Regents of the University of California */
  376. X
  377. Xstatic char sccsid[] = "@(#)readdir.c 4.3 8/8/82";
  378. X
  379. X#include <sys/types.h>
  380. X#include <dir.h>
  381. X
  382. X/*
  383. X * read an old stlye directory entry and present it as a new one
  384. X */
  385. X#define    ODIRSIZ    14
  386. X
  387. Xstruct    olddirect {
  388. X    ino_t    od_ino;
  389. X    char    od_name[ODIRSIZ];
  390. X};
  391. X
  392. X/*
  393. X * get next entry in a directory.
  394. X */
  395. Xstruct direct *
  396. Xreaddir(dirp)
  397. X    register DIR *dirp;
  398. X{
  399. X    register struct olddirect *dp;
  400. X    static struct direct dir;
  401. X
  402. X    for (;;) {
  403. X        if (dirp->dd_loc == 0) {
  404. X            dirp->dd_size = read(dirp->dd_fd, dirp->dd_buf, 
  405. X                DIRBLKSIZ);
  406. X            if (dirp->dd_size <= 0) {
  407. X                dirp->dd_size = 0;
  408. X                return NULL;
  409. X            }
  410. X        }
  411. X        if (dirp->dd_loc >= dirp->dd_size) {
  412. X            dirp->dd_loc = 0;
  413. X            continue;
  414. X        }
  415. X        dp = (struct olddirect *)(dirp->dd_buf + dirp->dd_loc);
  416. X        dirp->dd_loc += sizeof(struct olddirect);
  417. X        if (dp->od_ino == 0)
  418. X            continue;
  419. X        dir.d_ino = dp->od_ino;
  420. X        strncpy(dir.d_name, dp->od_name, ODIRSIZ);
  421. X        dir.d_name[ODIRSIZ] = '\0'; /* insure null termination */
  422. X        dir.d_namlen = strlen(dir.d_name);
  423. X        dir.d_reclen = DIRBLKSIZ;
  424. X        return (&dir);
  425. X    }
  426. X}
  427. !
  428. echo 'seekdir.c':
  429. sed 's/^X//' >'seekdir.c' <<'!'
  430. Xstatic char sccsid[] = "@(#)seekdir.c 4.9 3/25/83";
  431. X
  432. X#include <sys/param.h>
  433. X#include <dir.h>
  434. X
  435. X/*
  436. X * seek to an entry in a directory.
  437. X * Only values returned by "telldir" should be passed to seekdir.
  438. X */
  439. Xvoid
  440. Xseekdir(dirp, loc)
  441. X    register DIR *dirp;
  442. X    long loc;
  443. X{
  444. X    long curloc, base, offset;
  445. X    struct direct *dp;
  446. X    extern long lseek();
  447. X
  448. X    curloc = telldir(dirp);
  449. X    if (loc == curloc)
  450. X        return;
  451. X    base = loc & ~(DIRBLKSIZ - 1);
  452. X    offset = loc & (DIRBLKSIZ - 1);
  453. X    (void) lseek(dirp->dd_fd, base, 0);
  454. X    dirp->dd_size = 0;
  455. X    dirp->dd_loc = 0;
  456. X    while (dirp->dd_loc < offset) {
  457. X        dp = readdir(dirp);
  458. X        if (dp == NULL)
  459. X            return;
  460. X    }
  461. X}
  462. !
  463. echo 'telldir.c':
  464. sed 's/^X//' >'telldir.c' <<'!'
  465. Xstatic char sccsid[] = "@(#)telldir.c 4.1 2/21/82";
  466. X
  467. X#include <sys/types.h>
  468. X#include <dir.h>
  469. X
  470. X/*
  471. X * return a pointer into a directory
  472. X */
  473. Xlong
  474. Xtelldir(dirp)
  475. X    DIR *dirp;
  476. X{
  477. X    long lseek();
  478. X
  479. X    return (lseek(dirp->dd_fd, 0L, 1) - dirp->dd_size + dirp->dd_loc);
  480. X}
  481. !
  482. echo done
  483.